from functools import reduce

#函数本身也可以赋值给变量，即：变量可以指向函数

#既然变量可以指向函数，函数的参数能接收变量，那么一个函数就可以接收另一个函数作为参数，这种函数就称之为高阶函数。

#高阶函数

def addAbs(x,y,f):
   return f(x)+f(y)

print(addAbs(-1,1,abs))

def m_power(x):
    return x*x

def m_add(x,y):
    return x+y

#Map/Reduce


#Map概念：将function 作用到序列中的每个元素 并把结果作为新的Iterator返回
#因为Iterator是个惰性序列，要通过list将其计算出来

power_map=list(map(m_power,[1,2,3,4,5]))
print(power_map)

#多参数处理方式
addAbs_map=list(map(addAbs,[-1,-1,-1,-2,-4],[1,2,-2,2,2],[abs,abs,abs,abs,abs]))
#map(addAbs,[[-1,1,abs],[-1,2,abs],[-1,-2,abs],[-2,2,abs],[-4,2,abs]])
print(addAbs_map)


#Reduce概念：将function 作用到一个序列上，把结果和序列的下一个元素进行累计计算
#reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

add_reduce=reduce(m_add,map(m_power,[1,2,3,4,5]))
print(add_reduce)

# 利用map()函数，把用户输入的不规范的英文名字，变为首字母大写，其他小写的规范名字。
# 输入：['adam', 'LISA', 'barT']，输出：['Adam', 'Lisa', 'Bart']：
def FUpper(x):
    return x[0].upper()+x[1:].lower()

names=['adam', 'LISA', 'barT']

print(list(map(FUpper,names)))

#Python提供的sum()函数可以接受一个list并求和，请编写一个prod()函数，可以接受一个list并利用reduce()求积：
def sum_power(x,y):
    return x*y

print(reduce(sum_power,[1,2,3,4,5]))

#和map()类似，filter()也接收一个函数和一个序列。
#和map()不同的是，filter()把传入的函数依次作用于每个元素，然后根据返回值是True还是False决定保留还是丢弃该元素。

#留偶数
def l_old(x):
    return x%2==0

print(list(filter(l_old,[1,2,3,4,5,6,7,8])))

#去空字符串
def l_empty(x):
    return x and x.strip()

print(list(filter(l_empty, ['A', '', 'B', None, 'C', '  '])))

#用filter求素数 ( 存疑 )
def _odd_iter():
    n = 1
    while True:
        n = n + 2
        yield n

def _not_divisible(n):
    return lambda x: x % n > 0


def primes():
    yield 2
    it = _odd_iter() # 初始序列
    while True:
        n = next(it) # 返回序列的第一个数
        yield n
        it = filter(_not_divisible(n), it) # 构造新序列


# 打印1000以内的素数:
for n in primes():
    if n < 1000:
        print(n)
    else:
        break


#排序 sorted
# sorted()函数也是一个高阶函数，它还可以接收一个key函数来实现自定义的排序，例如按绝对值大小排序
print(sorted([36, 5, -12, 9, -21]))

print(sorted([36, 5, -12, 9, -21],key=abs))

print(sorted([36, 5, -12, 9, -21],key=abs,reverse=True))


